IOC是一個oop重要的程式設計思想。
此文帶著大家初探 IOC(控制反轉) , DI(依賴注入) ~~
案例解釋:
小明是個愛乾淨的人,但他工作時常加班導致
學一個技術或思想前我們必須先了解,這個技術或思想可為我們解決什麼問題。
Ioc(Inversion of Control)控制反轉
**控制反轉是一個設計思想 **
簡單解釋
A物件程式內部需要使用B物件 A,B物件中有依賴的成份
控制反轉把原本A對B直接控制權移交給由第三方容器
降低A對B物件的耦合程度,並讓雙方都倚賴抽象。
IoC經典實現對象設計法則 好萊塢法則:“別找我們,我們找你”
系統中模組建議依賴抽象,因為各個模組間不需要知道對方太多細節(實作),知道越多耦合越強。
DI—Dependency Injection 依賴注入
把被依賴物件注入被動接收物件中
案例解釋:
小明是個愛乾淨的人,但他工作時常加班導致房間雜亂,他不能忍受此狀況,所以小明去找一個清潔阿姨每天幫忙他打掃家裡
哪天阿姨哪天有事不能打掃,小明就必須要再去找人來幫忙打掃,由此可知小明耦合阿姨
如果今天是....
小明把他要的條件給「打掃仲介公司」,仲介公司幫他尋找有沒有符合小明需求的打掃阿姨,假如今天A阿姨請假了,仲介公司會自動找另一個符合需求B阿姨幫忙打掃...
原本小明需耦合於打掃阿姨,現在被「仲介公司」做了控制反轉讓「仲介公司」來提供打掃阿姨。
小明不用管是否今天有人會來打掃,「仲介公司」會幫小明找到一個掃地阿姨。
「打掃阿姨」可看作 被依賴物件
在使用IOC容器前需先了解雙方的依賴關係(誰依賴誰?)
上述還有一個很重要的觀念是,依賴和被接收對象要倚賴抽象。
範例使用:VS2015
IOC容器:AutoFac
下面範例來說明上面的例子
小明自己依賴於掃地阿姨
依賴程式碼寫在小明類別內部日後要更改只能動內部程式碼。
/// <summary>
/// 小明直接依賴 Aunt 不是依賴抽象
/// 日後要改必須動內部
/// </summary>
public class Mine
{
public Aunt aunt = new Aunt();
public void Room()
{
aunt.Swapping();
}
}
呼叫使用時
Mine mine = new Mine();
mine.Room();
小明找仲介公司
仲介公司(Ioc容器)
在仲介公司內註冊需求,讓仲介公司日後幫你找人(註冊的類別)
/// <summary>
/// 仲介公司
/// </summary>
/// <returns></returns>
private static IContainer MiddleCompany()
{
ContainerBuilder builder = new ContainerBuilder();
//在仲介公司裡寫需求人申請單
builder.RegisterType<MineWithMiddle>();
//小明所需打掃阿姨需求
builder.RegisterType<Aunt>().As<ISwapable>();
return builder.Build();
}
使用起來
IContainer middleCompany = MiddleCompany();
//仲介公司(IOC AutoFac)自動幫小明注入一個打掃阿姨
MineWithMiddle mineWithMiddle = middleCompany.Resolve<MineWithMiddle>();
mineWithMiddle.Room();
總結:
雖然上面程式碼執行結果一樣,但內部結構和日後擴展性卻截然不同
重點:系統中模組建議依賴抽象,因為各個模組間不需要知道對方太多細節(實作),知道越多耦合越強。
像網頁瀏覽器和伺服器是依賴Http協議,用戶端不管是手機.電腦,平板,伺服器端php,asp.net,java都可互相交信,依賴Http協議共用的合約
此文同步發布小弟部落格 : https://isdaniel.github.io/ioc-di/
這些說明看過很多,但怎麼看都看不懂很抽象,明明在寫api也安裝Unity用了DI(依賴注入)也用的快爛了,但網路上在寫的說明就是永遠也看不懂,很多功能都是原本寫好照用,在copy拿來用,用了也不懂,想懂了一堆說明後,覺得為什麼要搞成這樣麻煩抽象,說明不就是要說到連不會的人看的懂,但感覺是給懂的人看,但懂的又會有幾人,雖上面的說明已經說的我覺得已經懂的人或快懂的人會覺得寫的很好,我只能說IOC(控制反轉) , DI(依賴注入) 這名字取的不好,一個不好的名字就需要花一堆文字來解說,但說到最後還是不知道在說什麼,我知道要說明的人已經很努力,但只能說發明這個東西的人把名稱取的太爛
控制反轉,依賴注入 是英翻中所以大家才這樣叫,如果你有這樣困擾建議可以都用英文描述(資訊業是很喜歡創造新名詞的行業),名稱是拿來溝通使用
個人覺得會不會用和能不能正確使用才是重點,因為你會正確使用描述出來懂的人就會懂
名稱是拿來溝通使用,但現在用的名稱本身就抽象難懂,經你這一講我懂,英翻中,結果翻的不好,翻出一個控制反轉,依賴注入,像什麼Singleton 單例模式,這種也是亂翻一通,資訊業是很喜歡創造新名詞的行業真的創造的好像很高級要讓人家感覺很厲害,結果沒有人聽的懂創造出來的名稱,單例模式以前早有的東西在asp裏應該是Application 物件,就是程式執行只會產生一個共用,但現在人就愛搞鬼,結果弄出來的東西先是發明的名稱不貼切,在來怎麼解說都說不清楚了,以前的人做的東西簡簡單單實用可以用好久,現在的人一堆功能每個功能做的虛華不實,一下就壞一下就沒用改來改去
如果有理解 OOP 三大特性,六大原則和 DP 只是藉由 OOP 特性發揚光大,讓大家好去溝通(我是推薦大家看原文而非中文)
一下就壞一下就沒用改來改去
這個跟有沒有寫測試程式 & 程式設計師功力比較有關係
有很好解耦合的程式單元測試會很好寫